<?php
namespace App\Libs\Cache;

class Redis {
    /**
     * Holds initialized Redis connections.
     *
     * @var array
     */
    protected static $connections = array();
    protected static $timeout = 2;

    /**
     * By default the prefix of Redis key is the same as class name. But it
     * can be specified manually.
     *
     * @var string
     */
    protected static $prefix = NULL;

    /**
     * the server_id of the Redis Cluster
     *
     * @var int
     */

    protected static function setTimeout($timeout) {
        self::$timeout = $timeout;
    }

    /**
     * Initialize a Redis connection.
     * @TODO: support master/slave
     */
    protected static function connect ($host, $port, $timeout = 1) {
        $redis = new \Redis();
        $redis->connect($host, $port, $timeout);
        return $redis;
    }

    /**
     * Get an initialized Redis connection according to the key.
     */
    protected static function getRedis() {
        $config = self::getConfig();

        $host = $config['host'];
        $port = $config['port'];
        $connect_index = $host . ":" . $port;
        if (!isset(self::$connections[$connect_index])) {
            self::$connections[$connect_index] = self::connect($host, $port);
        }
        return self::$connections[$connect_index];
    }

    protected static function getPrefix() {
        $class = get_called_class();
        if (!is_null($class::$prefix)) {
            return $class::$prefix;
        }
        return get_called_class();
    }

    /**
     * Get host conf
     */
    protected static function getConfig() {
        static $config;
        is_null($config) && $config = \App\Libs\Base\Config::instance()->redis;
        $count = count($config['unixsock']);
        $index = mt_rand(0, $count - 1);
        $conf = $config['unixsock'][$index];
        empty($conf['host']) && $conf = array();
        return $conf;
    }

    /**
     * Get real key
     */
    public static function getKey ($name) {
        if ($name == NULL) {return $name;}

        $class = get_called_class();
        $prefix = $class::getPrefix();
        $key = "{$prefix}:{$name}";
        return $key;
    }

    public static function __callStatic($method, $args) {
        $key = self::getKey($args[0]);
        ! is_null($key) && $args[0] = $key;

        try {
            $result = call_user_func_array(array(self::getRedis(), $method), $args);
        }
        catch (\RedisException $e) {
            $result = NULL;
        }

        return $result;
    }


    public static function multi() {
        throw  new \RedisException("unsupported command 'MULTI'");
    }

}
